#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void handler(int signum) {
    printf("Caught signal %d\n", signum);
}

int main() {
    sigset_t old_mask, new_mask;
    int ret;

    // 创建一个新的信号集，并添加SIGINT信号
    sigemptyset(&new_mask);
    sigaddset(&new_mask, SIGINT);

    // 使用SIG_BLOCK选项，将SIGINT信号添加到当前的阻塞信号集中
    ret = sigprocmask(SIG_BLOCK, &new_mask, NULL);
    if (ret == -1) {
        perror("sigprocmask SIG_BLOCK failed");
        return 1;
    }

    printf("SIGINT has been blocked. Send Ctrl+C to generate SIGINT...\n");

    // 模拟一些工作，期间SIGINT信号将被阻塞
    sleep(5);

    // 获取当前的阻塞信号集并存储在old_mask中
    ret = sigprocmask(SIG_BLOCK, NULL, &old_mask);
    if (ret == -1) {
        perror("sigprocmask read failed");
        return 1;
    }

    printf("Before unblocking: The blocked signals are: ");
    for (int i = 1; i < NSIG; ++i) {
        if (sigismember(&old_mask, i)) {
            printf("%d ", i);
        }
    }
    printf("\n");

    // 使用SIG_UNBLOCK选项，从当前的阻塞信号集中移除SIGINT
    ret = sigprocmask(SIG_UNBLOCK, &new_mask, NULL);
    if (ret == -1) {
        perror("sigprocmask SIG_UNBLOCK failed");
        return 1;
    }

    printf("SIGINT has been unblocked. Sending SIGINT now...\n");
    
    // 注册SIGINT信号的处理函数
    signal(SIGINT, handler);

    // 模拟发送一个SIGINT信号，由于刚才已经解除阻塞，现在进程会立即捕获到SIGINT
    raise(SIGINT);

    // 若进程没有因SIGINT退出，这里继续执行后续代码...

    return 0;
}